﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Xceed.Silverlight.Data.Stats;

namespace Xceed.Silverlight.Data
{
  internal sealed class DataPathFactory : DataItemFactory<DataPath>
  {
    #region Constructor

    internal DataPathFactory( ReactiveDataHelper dataHelper, GroupHandler groupHandler )
    {
      if( dataHelper == null )
        throw new ArgumentNullException( "dataHelper" );

      if( groupHandler == null )
        throw new ArgumentNullException( "groupHandler" );

      m_dataHelper = dataHelper;
      m_groupHandler = groupHandler;
    }

    #endregion

    protected internal override StatResults CreateDummyStatResults( StatParameters parameters )
    {
      List<StatResult> dummyResults = new List<StatResult>();

      foreach( StatFunction func in parameters.StatFunctions )
      {
        dummyResults.Add( new StatResult( null, true ) );
      }

      return new StatResults( dummyResults );
    }

    protected internal override DataPath CreateInstance( DataPath templateItem )
    {
      DataItem[] items = new DataItem[ m_groupHandler.GroupDescriptions.Count + 1 ];
      bool isUnCommonDescendant = false;
      GroupDataItem group = null;

      for( int i = 0; i < items.Length - 1; i++ )
      {
        group = null;

        if( templateItem != null && i < templateItem.Depth && !isUnCommonDescendant )
        {
          if( templateItem[ i ].IsLoaded )
          {
            DataPath currentTemplatePath = ( i == templateItem.Depth - 1 ) ? templateItem : templateItem.CreateAncestorPath( i + 1 );
            isUnCommonDescendant = true;
            if( m_dataHelper.IsGroupPath( currentTemplatePath ) )
            {
              if( !m_groupHandler.IsCollapsed( currentTemplatePath ) )
              {
                isUnCommonDescendant = false;
                Debug.Assert( templateItem[ i ] is GroupDataItem );
                group = new GroupDataItem( templateItem[ i ].Data );
              }
            }
          }
          else
          {
            Debug.Assert( templateItem[ i ] is GroupDataItem, "No other type of data is expected. May change with master detail or group headers" );
            group = ( GroupDataItem )templateItem[ i ];
          }
        }

        if( group == null )
        {
          group = new GroupDataItem( null, false );
        }
        items[ i ] = group;
      }

      items[ items.Length - 1 ] = new DataItem();

      return new DataPath( items, true );
    }

    protected internal override bool IsDummy( DataPath item )
    {
      return m_dataHelper.IsDummy( item );
    }

    //protected internal override bool HasParent( DataPath source )
    //{
    //  return ( source.Depth > 1 );
    //}

    //protected internal override object GetParentValue( DataPath sourceItem, int depth, ref bool leafReached )
    //{
    //  if( depth >= sourceItem.Depth )
    //    throw new ArgumentOutOfRangeException( "depth", "depth must be less than the depth of the specified DataPath." );

    //  if( depth == sourceItem.Depth - 1 )
    //    leafReached = true;

    //  return sourceItem.CreateAncestorPath( depth );
    //}

    //protected internal override object GetParentValue( DataPath item )
    //{
    //  return item.ParentPath;
    //}

    //protected internal override bool IsPartiallyInitialized( DataPath item )
    //{
    //  for( int i = 0; i < item.Depth; i++ )
    //  {
    //    if( item[ i ].IsLoaded )
    //      return true;
    //  }

    //  return false;
    //}

    //protected internal override bool IsCompletelyInitialized( DataPath item )
    //{
    //  for( int i = 0; i < item.Depth; i++ )
    //  {
    //    if( !item[ i ].IsLoaded )
    //      return false;
    //  }

    //  return true;
    //}

    //protected internal override bool IsParentEqualTo( DataPath item, object parentValue )
    //{
    //  return object.Equals( item.ParentPath, parentValue );
    //}

    #region Private Fields

    private readonly ReactiveDataHelper m_dataHelper;
    private readonly GroupHandler m_groupHandler;

    #endregion
  }
}
